#pragma once

#include "Enum.h"
#include <list>
#include <map>
#include <string>

class Player;
class Item;

struct RecipeItem {
	TypeHierarchy typeCategory;
	int type;
	bool required;
	int numRequired;
	std::string name;
};

class Recipe {
protected:
	RecipeType m_type;
	int m_currentItem;
	std::list<RecipeItem*>* m_recipe;
	std::map<RecipeItem*, std::list<Item*>> m_selectedItems;
	std::map<std::string, RecipeItem*> m_map;
	static RecipeItem* createRecipeItem(std::string name, TypeHierarchy typeCategory, int type, int numRequired = 1, bool required = true);
	Item* getSelectedItem(std::string name) const;
	void addRecipeItem(RecipeItem* item);
	RecipeItem* getRecipeItem(int num) const;
public:
	Recipe(RecipeType type);
	~Recipe();
	void craft(Player* player);
	void selectItem(Item* item);
	std::list<RecipeItem*>* getRecipe() const;
	bool canCraft(const Player* player) const;
	RecipeType getRecipeType() const;
	void clearSelectedItems();
	RecipeItem* getCurrentItem() const;
	int getCurrentItemAsInt() const;
	void skipItem();
	bool readyForCraft() const;
};

inline std::list<RecipeItem*>* Recipe::getRecipe() const {return m_recipe;}
inline RecipeType Recipe::getRecipeType() const {return m_type;}
inline RecipeItem* Recipe::getCurrentItem() const {return getRecipeItem(m_currentItem);}
inline int Recipe::getCurrentItemAsInt() const {return m_currentItem;}
inline void Recipe::skipItem() {m_currentItem++;}
inline bool Recipe::readyForCraft() const {return size_t(m_currentItem) == m_recipe->size();}
